/*
 * 无重复字符的最长子串
 * https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
 */
struct hash_node {
    int ch;
    int index;
    UT_hash_handle hh; /* makes this structure hashable */
};

struct hash_node *hash_table = NULL;

void add_node(struct hash_node *s) {
    HASH_ADD_INT(hash_table, ch, s);
}
// 2. 在哈希表中查找一个对象：
struct hash_node *find_node(int ch) {
    struct hash_node *s;
    HASH_FIND_INT(hash_table, &ch, s);
    return s;
}
// 3. 从哈希表中删除一个对象：
void delete_node(struct hash_node *user) {
    HASH_DEL(hash_table, user);  
}

int lengthOfLongestSubstring(char * s){
    int len = strlen(s);
    if (len == 0) return 0;
    hash_table = NULL;
    int old = 1;
    int new = 0;
    int max = old;
    for (int j = 0; j < len; j++) {
        struct hash_node *it = find_node(s[j]);
        if (it == NULL) {
            struct hash_node *tmp = (struct hash_node *)malloc(sizeof(struct hash_node));
            tmp->ch = s[j];
            tmp->index = j;
            add_node(tmp);
            if (j != 0) {
                new = old + 1;
                old = new;
            }
        } else {
            new = (j - it->index > old) ? old + 1 : j - it->index;
            old = new;
            it->index = j;
        }
        max = new > max ? new : max;
    }

    return max;
}